package com.morizhang.merchanmanager.api.plugins.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.morizhang.merchanmanager.api.bean.MerChanManagerException;
import com.morizhang.merchanmanager.api.dao.*;
import com.morizhang.merchanmanager.api.dao.external.impl.GsspaqwCommodityDataExternalDao;
import com.morizhang.merchanmanager.api.dao.external.impl.TencentCommodityDataExternalDaoImpl;
import com.morizhang.merchanmanager.api.model.*;
import com.morizhang.merchanmanager.api.plugins.BasicWareManage;
import com.morizhang.merchanmanager.api.plugins.PluginAnnotation;
import com.morizhang.merchanmanager.api.utils.SerialNoGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@PluginAnnotation(name = "BasicWareManage")
public class BasicWareManageImpl implements BasicWareManage {
    @Autowired
    private CommodityDataDao commodityDataDao;
    @Autowired
    private TencentCommodityDataExternalDaoImpl tencentCommodityDataDao;
    @Autowired
    private CommodityExpireDayDao commodityExpireDayDao;
    @Autowired
    private GsspaqwCommodityDataExternalDao gsspaqwCommodityDataExternalDao;
    @Autowired
    private PriceInfoDao priceInfoDao;

    @Override
    public CommodityDataModel queryCommodity(String barCode) {
        CommodityDataModel result = commodityDataDao.queryCommodityByBarcode(barCode);
        if (result == null) {
            JSONObject externalResult = tencentCommodityDataDao.getData(barCode);
            result = JSON.toJavaObject(externalResult, CommodityDataModel.class);
        }

        CommodityExpireModel expireResult = commodityExpireDayDao.queryCommodityExpireByBarcode(barCode);
        if (expireResult != null)
            result.setSaveDate(expireResult.getExpireDays());
        else {
            JSONObject externalResult = gsspaqwCommodityDataExternalDao.getData(barCode);
            if (externalResult != null)
                result.setSaveDate(externalResult.getString("saveDate"));
        }

        //在售价表中同步增加商品信息
        PriceModel priceInfo = priceInfoDao.queryCommoditySellPriceByBarcode(barCode);
        if (priceInfo == null) {
            PriceModel newPriceInfo = new PriceModel();
            newPriceInfo.setBarCode(barCode);
            priceInfoDao.addCommoditySellPrice(newPriceInfo);
        }
        return result;
    }

    @Override
    public void addCommodity(CommodityDataModel commodityDataModel, CommodityExpireModel commodityExpireModel) {
        commodityDataDao.addNewRecord(commodityDataModel);
        if (commodityExpireModel == null)
            return;
        commodityExpireDayDao.addNewExpireRecord(commodityExpireModel);
    }

    @Override
    public void updateCommodity(CommodityDataModel commodityDataModel) {
        commodityDataDao.updateCommodity(commodityDataModel);
    }

    @Autowired
    private WarehouseShelfInfoDao warehouseShelfInfoDao;

    @Override
    public List<WarehouseShelfModel> selectAllWarehouse() {
        return warehouseShelfInfoDao.selectAllWarehouse();
    }

    @Override
    public WarehouseShelfModel queryWarehouseInfo(String warehouseName) {
        return warehouseShelfInfoDao.queryWarehouseInfo(warehouseName);
    }

    @Override
    public void addWarehouseInfo(WarehouseShelfModel warehouseModel) throws Exception {
        if (warehouseModel.getWarehouseNo() == null)
            warehouseModel.setWarehouseNo(SerialNoGenerator.newSerialNo());
        warehouseShelfInfoDao.addWarehouseInfo(warehouseModel);
    }

    @Override
    public void deleteWarehouseInfo(String warehouseName) {
        warehouseShelfInfoDao.deleteWarehouseInfo(warehouseName);
    }

    @Override
    public void updateWarehouseInfo(WarehouseShelfModel warehouseModel) {
        warehouseShelfInfoDao.updateWarehouseInfo(warehouseModel);
    }

    @Override
    public List<CommodityWareModel> queryWarehouseCommodityInfo(String warehouseName) {
        return null;
    }

    @Override
    public List<WarehouseShelfModel> selectAllWarehouseSection(String warehouseNo) {
        return warehouseShelfInfoDao.selectAllWarehouseSection(warehouseNo);
    }

    @Override
    public WarehouseShelfModel queryWarehouseSectionInfo(String warehouseSectionNo) {
        return warehouseShelfInfoDao.queryWarehouseSectionInfo(warehouseSectionNo);
    }

    @Override
    public void addWarehouseSectionInfo(WarehouseShelfModel warehouseSectionModel) throws Exception {
        if (warehouseSectionModel.getWarehouseSectionNo() == null)
            warehouseSectionModel.setWarehouseSectionNo(SerialNoGenerator.newSerialNo());
        warehouseShelfInfoDao.addWarehouseSectionInfo(warehouseSectionModel);
    }

    @Override
    public void deleteWarehouseSectionInfo(String warehouseSectionNo) {
        warehouseShelfInfoDao.deleteWarehouseSectionInfo(warehouseSectionNo);
    }

    @Override
    public void updateWarehouseSectionInfo(WarehouseShelfModel warehouseSectionModel) {
        warehouseShelfInfoDao.updateWarehouseSectionInfo(warehouseSectionModel);
    }

    @Override
    public List<CommodityWareModel> queryWarehouseSectionCommodityInfo(String warehouseSectionNo) {
        return null;
    }

    @Override
    public List<WarehouseShelfModel> selectAllWarehouseShelf(String warehouseSectionNo) {
        return warehouseShelfInfoDao.selectAllWarehouseShelf(warehouseSectionNo);
    }

    @Override
    public WarehouseShelfModel queryWarehouseShelfInfo(String warehouseName) {
        return warehouseShelfInfoDao.queryWarehouseShelfInfo(warehouseName);
    }

    @Override
    public void addWarehouseShelfInfo(WarehouseShelfModel warehouseShelfModel) throws Exception {
        if (warehouseShelfModel.getWarehouseShelfNo() == null)
            warehouseShelfModel.setWarehouseShelfNo(SerialNoGenerator.newSerialNo());
        warehouseShelfInfoDao.addWarehouseShelfInfo(warehouseShelfModel);
    }

    @Override
    public void deleteWarehouseShelfInfo(String warehouseShelfNo) {
        warehouseShelfInfoDao.deleteWarehouseShelfInfo(warehouseShelfNo);
    }

    @Override
    public void updateWarehouseShelfInfo(WarehouseShelfModel warehouseShelfModel) {
        warehouseShelfInfoDao.updateWarehouseShelfInfo(warehouseShelfModel);
    }

    @Override
    public List<CommodityWareModel> queryWarehouseShelfCommodityInfo(String warehouseShelfNo) {
        List<CommodityLocationModel> searchResult = commodityStorageDao.queryCommodityStorageByWarehouseShelf(warehouseShelfNo);
        List<CommodityWareModel> returnResult = new ArrayList<>();
        for (CommodityLocationModel singleSearchResult : searchResult) {
            CommodityWareModel singleReturnResult = new CommodityWareModel(singleSearchResult);
            singleReturnResult.setShelfNo(singleSearchResult.getWarehouseShelfNo());
            singleReturnResult.setProductName(commodityDataDao.queryCommodityByBarcode(singleSearchResult.getBarCode()).getProductName());
            StockModel queryProductTimeParameter = new StockModel();
            queryProductTimeParameter.setBarCode(singleSearchResult.getBarCode());
            queryProductTimeParameter.setBatchNo(singleSearchResult.getBatchNo());
            singleReturnResult.setProductTime(commodityStorageDao.queryCommodityStorage(queryProductTimeParameter).getProductTime());

            CommodityExpireModel expireModel = commodityExpireDayDao.queryCommodityExpireByBarcode(singleReturnResult.getBarCode());
            if (expireModel != null)
                singleReturnResult.setExpire(expireModel.getExpireDays());

            returnResult.add(singleReturnResult);
        }
        return returnResult;
    }

    @Autowired
    ShopShelfInfoDao shopShelfInfoDao;

    @Override
    public List<ShopShelfModel> selectAllShop() {
        return shopShelfInfoDao.selectAllShop();
    }

    @Override
    public ShopShelfModel queryShopInfo(String shopName) {
        return shopShelfInfoDao.queryShopInfo(shopName);
    }

    @Override
    public void addShopInfo(ShopShelfModel shopModel) throws Exception {
        if (shopModel.getShopNo() == null)
            shopModel.setShopNo(SerialNoGenerator.newSerialNo());
        shopShelfInfoDao.addShopInfo(shopModel);
    }

    @Override
    public void deleteShopInfo(String shopName) {
        shopShelfInfoDao.deleteShopInfo(shopName);
    }

    @Override
    public void updateShopInfo(ShopShelfModel shopModel) {
        shopShelfInfoDao.updateShopInfo(shopModel);
    }

    @Override
    public List<CommodityWareModel> queryShopCommodityInfo(String shopName) {
        return null;
    }

    @Override
    public List<ShopShelfModel> selectAllShopSection(String shopNo) {
        return shopShelfInfoDao.selectAllShopSection(shopNo);
    }

    @Override
    public ShopShelfModel queryShopSectionInfo(String shopSectionNo) {
        return shopShelfInfoDao.queryShopSectionInfo(shopSectionNo);
    }

    @Override
    public void addShopSectionInfo(ShopShelfModel shopSectionModel) throws Exception {
        if (shopSectionModel.getShopSectionNo() == null)
            shopSectionModel.setShopSectionNo(SerialNoGenerator.newSerialNo());
        shopShelfInfoDao.addShopSectionInfo(shopSectionModel);
    }

    @Override
    public void deleteShopSectionInfo(String shopSectionNo) {
        shopShelfInfoDao.deleteShopSectionInfo(shopSectionNo);
    }

    @Override
    public void updateShopSectionInfo(ShopShelfModel shopSectionModel) {
        shopShelfInfoDao.updateShopSectionInfo(shopSectionModel);
    }

    @Override
    public List<CommodityWareModel> queryShopSectionCommodityInfo(String shopSectionNo) {
        return null;
    }

    @Override
    public List<ShopShelfModel> selectAllShopShelf(String shopSectionNo) {
        return shopShelfInfoDao.selectAllShopShelf(shopSectionNo);
    }

    @Override
    public ShopShelfModel queryShopShelfInfo(String shopName) {
        return shopShelfInfoDao.queryShopShelfInfo(shopName);
    }

    @Override
    public void addShopShelfInfo(ShopShelfModel shopShelfModel) throws Exception {
        if (shopShelfModel.getShopShelfNo() == null)
            shopShelfModel.setShopShelfNo(SerialNoGenerator.newSerialNo());
        shopShelfInfoDao.addShopShelfInfo(shopShelfModel);
    }

    @Override
    public void deleteShopShelfInfo(String shopShelfNo) {
        shopShelfInfoDao.deleteShopShelfInfo(shopShelfNo);
    }

    @Override
    public void updateShopShelfInfo(ShopShelfModel shopShelfModel) {
        shopShelfInfoDao.updateShopShelfInfo(shopShelfModel);
    }

    @Autowired
    private CommodityStorageDao commodityStorageDao;

    @Override
    @Transactional
    public void locateCommodity(StockModel unlocatedCommodity, String warehouseShelfNo) throws MerChanManagerException {
        //查询传入的这一批将要操作的货品信息
        StockModel operatingUnlocationCommodity = commodityStorageDao.queryCommodityUnlocation(unlocatedCommodity);
        if (operatingUnlocationCommodity == null) {
            return;
        }
        //如果将设置的数量与未分配的一致，则删除这条未分配记录
        if (operatingUnlocationCommodity.getAmountNow() == unlocatedCommodity.getAmountNow()) {
            commodityStorageDao.deleteCommodityUnlocation(operatingUnlocationCommodity.getSerialNo());
        }
        //如果将设置的数量少于未分配的，则更新这条未分配记录
        if (operatingUnlocationCommodity.getAmountNow() > unlocatedCommodity.getAmountNow()) {
            int unlocationAmountNow = operatingUnlocationCommodity.getAmountNow();
            unlocationAmountNow = unlocationAmountNow - unlocatedCommodity.getAmountNow();
            operatingUnlocationCommodity.setAmountNow(unlocationAmountNow);
            commodityStorageDao.updateCommodityUnlocation(operatingUnlocationCommodity);
        }

        //组装带写入的货物位置信息模型
        CommodityLocationModel commodityLocationModel = new CommodityLocationModel(unlocatedCommodity);
        commodityLocationModel.setWarehouseShelfNo(warehouseShelfNo);

        //查询是否存在同批次的货物储存在目标货架上
        List<CommodityLocationModel> existCommodityLocation = commodityStorageDao.queryCommodityLocation(commodityLocationModel);
        if (existCommodityLocation != null && !existCommodityLocation.isEmpty()) {
            for (CommodityLocationModel eachExist : existCommodityLocation) {
                if (eachExist.getWarehouseShelfNo().compareTo(warehouseShelfNo) == 0) {
                    int existAmount = eachExist.getAmountNow();
                    existAmount += unlocatedCommodity.getAmountNow();
                    commodityLocationModel.setAmountNow(existAmount);
                    commodityLocationModel.setSerialNo(eachExist.getSerialNo());
                    commodityStorageDao.updateCommodityLocation(commodityLocationModel);
                    return;
                }
            }
        }

        //不存在同批次同货架的情况，新增一条记录
        try {
            String serialNo = SerialNoGenerator.newSerialNo();
            commodityLocationModel.setSerialNo(serialNo);
        } catch (Exception e) {
            MerChanManagerException exception = new MerChanManagerException();
            throw exception;
        }
        commodityStorageDao.addCommodityLocation(commodityLocationModel);
    }

    @Transactional
    @Override
    public void unlocateCommodity(CommodityLocationModel commodityLocationModel) throws MerChanManagerException {
        //查询将要下架的货物
        CommodityLocationModel readyUnlocation = commodityStorageDao.queryCommodityLocationByBarcodeBatchNoShelfNo(commodityLocationModel);
        if (readyUnlocation == null) {
            return;
        }
        //检查在货架上的数量
        int onShelfAmount = readyUnlocation.getAmountNow();
        if (onShelfAmount < commodityLocationModel.getMoveAmount())
            return;
        if (onShelfAmount == commodityLocationModel.getMoveAmount()) {
            commodityStorageDao.deleteCommodityLocation(readyUnlocation.getSerialNo());
        }
        CommodityLocationModel updatedLocation = (CommodityLocationModel)readyUnlocation.clone();
        updatedLocation.setAmountNow(updatedLocation.getAmountNow() - commodityLocationModel.getMoveAmount());
        commodityStorageDao.updateCommodityLocation(updatedLocation);

        //修改未分配记录
        StockModel updatedUnlocation = new StockModel();
        updatedUnlocation.setBarCode(commodityLocationModel.getBarCode());
        updatedUnlocation.setBatchNo(commodityLocationModel.getBatchNo());
        StockModel searchResult = commodityStorageDao.queryCommodityUnlocation(updatedUnlocation);
        if (searchResult == null) {
            try {
                String serialNo = SerialNoGenerator.newSerialNo();
                updatedUnlocation.setSerialNo(serialNo);
            } catch (Exception e) {
                MerChanManagerException exception = new MerChanManagerException();
                throw exception;
            }
            updatedUnlocation.setAmountNow(commodityLocationModel.getMoveAmount());
            commodityStorageDao.addCommodityUnlocation(updatedUnlocation);
            return;
        }

        updatedUnlocation = searchResult;
        updatedUnlocation.setAmountNow(searchResult.getAmountNow() + commodityLocationModel.getMoveAmount());
        commodityStorageDao.updateCommodityUnlocation(updatedUnlocation);
    }

    @Transactional
    @Override
    public void moveCommodityInWarehouse(CommodityLocationModel moveCommodityInfo) throws MerChanManagerException {
        //查询要移动的货物的存货信息
        List<CommodityLocationModel> commodityStorageInfo = commodityStorageDao.queryCommodityLocation(moveCommodityInfo);

        //不存在这样的货物
        if (commodityStorageInfo == null || commodityStorageInfo.isEmpty()) {
            return;
        }

        //构造原货架信息和目标货架信息，以待写入
        CommodityLocationModel sourceShelfCommodityInfo = (CommodityLocationModel) moveCommodityInfo.clone();
        CommodityLocationModel targetShelfCommodityInfo = (CommodityLocationModel) moveCommodityInfo.clone();

        //标识是否已经完成的目标货架的信息写入
        int targetShelfCheckedFlag = 0;

        //查询要移动的这批货物的库存量
        for (CommodityLocationModel eachExist : commodityStorageInfo) {
            //检查到源货架上的库存
            if (eachExist.getWarehouseShelfNo().compareTo(moveCommodityInfo.getSourceWarehouseShelfNo()) == 0) {
                int sourceShelfAmount = eachExist.getAmountNow();
                //源货架上的货物不足
                if (sourceShelfAmount < moveCommodityInfo.getMoveAmount()) {
                    return;
                }
                //源货架上货物全部被移完
                if (sourceShelfAmount == moveCommodityInfo.getMoveAmount()) {
                    commodityStorageDao.deleteCommodityLocation(eachExist.getSerialNo());
                    continue;
                }
                sourceShelfAmount -= moveCommodityInfo.getMoveAmount();
                sourceShelfCommodityInfo.setAmountNow(sourceShelfAmount);
                sourceShelfCommodityInfo.setWarehouseShelfNo(eachExist.getWarehouseShelfNo());
                sourceShelfCommodityInfo.setSerialNo(eachExist.getSerialNo());
                commodityStorageDao.updateCommodityLocation(sourceShelfCommodityInfo);
                continue;
            }
            //检查到目标货架上的库存
            if (eachExist.getWarehouseShelfNo().compareTo(moveCommodityInfo.getDestinationWarehouseShelfNo()) == 0) {
                int targetShelfAmount = eachExist.getAmountNow();
                targetShelfAmount += moveCommodityInfo.getMoveAmount();
                targetShelfCommodityInfo.setSerialNo(eachExist.getSerialNo());
                targetShelfCommodityInfo.setAmountNow(targetShelfAmount);
                targetShelfCommodityInfo.setWarehouseShelfNo(eachExist.getWarehouseShelfNo());
                commodityStorageDao.updateCommodityLocation(targetShelfCommodityInfo);
                targetShelfCheckedFlag = 1;
            }
        }

        //目标货架上不存在这批货物，新增记录
        if (targetShelfCheckedFlag == 0) {
            try {
                String serialNo = SerialNoGenerator.newSerialNo();
                targetShelfCommodityInfo.setSerialNo(serialNo);
            } catch (Exception e) {
                MerChanManagerException exception = new MerChanManagerException();
                throw exception;
            }
            targetShelfCommodityInfo.setAmountNow(moveCommodityInfo.getMoveAmount());
            targetShelfCommodityInfo.setWarehouseShelfNo(moveCommodityInfo.getDestinationWarehouseShelfNo());
            commodityStorageDao.addCommodityLocation(targetShelfCommodityInfo);
        }
    }

    @Transactional
    @Override
    public void moveCommodityInShop(CommodityLocationModel moveCommodityInfo) throws MerChanManagerException {
        //查询要移动的货物的存货信息
        List<CommodityLocationModel> commodityShopInfo = commodityStorageDao.queryCommodityShopLocation(moveCommodityInfo);

        //不存在这样的货物
        if (commodityShopInfo == null || commodityShopInfo.isEmpty()) {
            return;
        }

        //构造原货架信息和目标货架信息，以待写入
        CommodityLocationModel sourceShelfCommodityInfo = (CommodityLocationModel) moveCommodityInfo.clone();
        CommodityLocationModel targetShelfCommodityInfo = (CommodityLocationModel) moveCommodityInfo.clone();

        //标识是否已经完成的目标货架的信息写入
        int targetShelfCheckedFlag = 0;

        //查询要移动的这批货物的库存量
        for (CommodityLocationModel eachExist : commodityShopInfo) {
            //检查到源货架上的库存
            if (eachExist.getShopShelfNo().compareTo(moveCommodityInfo.getSourceShopShelfNo()) == 0) {
                int sourceShelfAmount = eachExist.getAmountNow();
                //源货架上的货物不足
                if (sourceShelfAmount < moveCommodityInfo.getMoveAmount()) {
                    return;
                }
                //源货架上货物全部被移完
                if (sourceShelfAmount == moveCommodityInfo.getMoveAmount()) {
                    commodityStorageDao.deleteCommodityShopLocation(eachExist.getSerialNo());
                    continue;
                }
                sourceShelfAmount -= moveCommodityInfo.getMoveAmount();
                sourceShelfCommodityInfo.setAmountNow(sourceShelfAmount);
                sourceShelfCommodityInfo.setShopShelfNo(eachExist.getShopShelfNo());
                sourceShelfCommodityInfo.setSerialNo(eachExist.getSerialNo());
                commodityStorageDao.updateCommodityShopLocation(sourceShelfCommodityInfo);
                continue;
            }
            //检查到目标货架上的库存
            if (eachExist.getShopShelfNo().compareTo(moveCommodityInfo.getDestinationShopShelfNo()) == 0) {
                int targetShelfAmount = eachExist.getAmountNow();
                targetShelfAmount += moveCommodityInfo.getMoveAmount();
                targetShelfCommodityInfo.setSerialNo(eachExist.getSerialNo());
                targetShelfCommodityInfo.setAmountNow(targetShelfAmount);
                targetShelfCommodityInfo.setShopShelfNo(eachExist.getShopShelfNo());
                commodityStorageDao.updateCommodityShopLocation(targetShelfCommodityInfo);
                targetShelfCheckedFlag = 1;
            }
        }

        //目标货架上不存在这批货物，新增记录
        if (targetShelfCheckedFlag == 0) {
            try {
                String serialNo = SerialNoGenerator.newSerialNo();
                targetShelfCommodityInfo.setSerialNo(serialNo);
            } catch (Exception e) {
                MerChanManagerException exception = new MerChanManagerException();
                throw exception;
            }
            targetShelfCommodityInfo.setAmountNow(moveCommodityInfo.getMoveAmount());
            targetShelfCommodityInfo.setShopShelfNo(moveCommodityInfo.getDestinationShopShelfNo());
            commodityStorageDao.addCommodityShopLocation(targetShelfCommodityInfo);
        }
    }

    @Autowired
    CommoditySellingDao commoditySellingDao;

    @Transactional
    @Override
    public void moveCommodityToShop(CommodityLocationModel moveCommodityInfo) throws Exception {
        //查询要移动的货物的存货信息
        List<CommodityLocationModel> commodityStorageInfo = commodityStorageDao.queryCommodityLocation(moveCommodityInfo);

        //不存在这样的货物
        if (commodityStorageInfo == null || commodityStorageInfo.isEmpty()) {
            return;
        }

        //构造原货架信息和目标货架信息，以待写入
        CommodityLocationModel sourceShelfCommodityInfo = (CommodityLocationModel) moveCommodityInfo.clone();
        CommodityLocationModel targetShelfCommodityInfo = (CommodityLocationModel) moveCommodityInfo.clone();

        //查询要移动的这批货物的库存量
        for (CommodityLocationModel eachExist : commodityStorageInfo) {
            //检查到源货架上的库存
            if (eachExist.getWarehouseShelfNo().compareTo(moveCommodityInfo.getSourceWarehouseShelfNo()) == 0) {
                int sourceShelfAmount = eachExist.getAmountNow();
                //源货架上的货物不足
                if (sourceShelfAmount < moveCommodityInfo.getMoveAmount()) {
                    return;
                }
                //源货架上货物全部被移完
                if (sourceShelfAmount == moveCommodityInfo.getMoveAmount()) {
                    commodityStorageDao.deleteCommodityLocation(eachExist.getSerialNo());
                    break;
                }
                sourceShelfAmount -= moveCommodityInfo.getMoveAmount();
                sourceShelfCommodityInfo.setAmountNow(sourceShelfAmount);
                sourceShelfCommodityInfo.setWarehouseShelfNo(eachExist.getWarehouseShelfNo());
                sourceShelfCommodityInfo.setSerialNo(eachExist.getSerialNo());
                commodityStorageDao.updateCommodityLocation(sourceShelfCommodityInfo);
                break;
            }
        }

        targetShelfCommodityInfo.setShopShelfNo(moveCommodityInfo.getDestinationShopShelfNo());
        //查询目标货架上是否已有该货物
        CommodityLocationModel targetShelfCommodityInfoNow = commodityStorageDao.queryCommodityShopLocationByBarcodeShelfNo(targetShelfCommodityInfo);
        if (targetShelfCommodityInfoNow == null) {
            //新增目标货架的记录
            try {
                String serialNo = SerialNoGenerator.newSerialNo();
                targetShelfCommodityInfo.setSerialNo(serialNo);
            } catch (Exception e) {
                MerChanManagerException exception = new MerChanManagerException();
                throw exception;
            }
            targetShelfCommodityInfo.setAmountNow(moveCommodityInfo.getMoveAmount());
            targetShelfCommodityInfo.setShopShelfNo(moveCommodityInfo.getDestinationShopShelfNo());
            commodityStorageDao.addCommodityShopLocation(targetShelfCommodityInfo);
            targetShelfCommodityInfoNow = targetShelfCommodityInfo;
        } else {
            //直接在已有记录上修改
            targetShelfCommodityInfoNow.setAmountNow(targetShelfCommodityInfoNow.getAmountNow() + moveCommodityInfo.getMoveAmount());
            commodityStorageDao.updateCommodityShopLocation(targetShelfCommodityInfoNow);
        }

        //更新在售信息
        CommoditySellingModel queryParameter = new CommoditySellingModel(targetShelfCommodityInfoNow);
        CommoditySellingModel commoditySelling = commoditySellingDao.queryCommoditySellingByBarcodeSelfNo(queryParameter);
        if (commoditySelling == null) {
            queryParameter.setSerialNo(SerialNoGenerator.newSerialNo());
            commoditySellingDao.addCommoditySelling(queryParameter);
        }
    }

    @Transactional
    @Override
    public void offShelf(CommodityLocationModel moveCommodityInfo) throws MerChanManagerException {
        //查询源货架上的存量
        CommodityLocationModel sourceShelfCommodityInfo = commodityStorageDao.queryCommodityShopLocationByBarcodeShelfNo(moveCommodityInfo);
        if (sourceShelfCommodityInfo == null) {
            return;
        }
        int sourceShelfCommodityAmount = sourceShelfCommodityInfo.getAmountNow();
        if (sourceShelfCommodityAmount < moveCommodityInfo.getMoveAmount()) {
            return;
        }
        if (sourceShelfCommodityAmount == moveCommodityInfo.getMoveAmount()) {
            commodityStorageDao.deleteCommodityShopLocation(sourceShelfCommodityInfo.getSerialNo());
        }
        if (sourceShelfCommodityAmount > moveCommodityInfo.getMoveAmount()) {
            sourceShelfCommodityInfo.setAmountNow(sourceShelfCommodityAmount - moveCommodityInfo.getMoveAmount());
            commodityStorageDao.updateCommodityShopLocation(sourceShelfCommodityInfo);
        }

        //查询退货区域的存量
        CommodityLocationModel commodityReturnedInfo = commodityStorageDao.queryCommodityReturnedByBarcode(moveCommodityInfo.getBarCode());
        if (commodityReturnedInfo == null) {
            CommodityLocationModel targetCommodityInfo = new CommodityLocationModel();
            try {
                String serialNo = SerialNoGenerator.newSerialNo();
                targetCommodityInfo.setSerialNo(serialNo);
            } catch (Exception e) {
                MerChanManagerException exception = new MerChanManagerException();
                throw exception;
            }
            targetCommodityInfo.setBarCode(moveCommodityInfo.getBarCode());
            targetCommodityInfo.setAmountNow(moveCommodityInfo.getMoveAmount());
            commodityStorageDao.addCommodityReturned(targetCommodityInfo);
            return;
        }
        commodityReturnedInfo.setAmountNow(commodityReturnedInfo.getAmountNow() + moveCommodityInfo.getMoveAmount());
        commodityStorageDao.updateCommodityReturned(commodityReturnedInfo);
    }

    @Override
    public StockModel queryCommodityStorage(StockModel stockModel) {
        return commodityStorageDao.queryCommodityStorage(stockModel);
    }

    @Override
    public List<CommodityLocationModel> queryCommodityLocation(CommodityLocationModel commodityLocationModel) {
        String serialNo = commodityLocationModel.getSerialNo();
        if (serialNo != null && serialNo.length() > 0) {
            CommodityLocationModel searchResult = commodityStorageDao.queryCommodityLocationBySerialNo(serialNo);
            if (searchResult != null) {
                List<CommodityLocationModel> result = new ArrayList<>();
                result.add(searchResult);
                return result;
            }
            return null;
        }
        return commodityStorageDao.queryCommodityLocation(commodityLocationModel);
    }

    @Override
    public void updateCommodityLocation(CommodityLocationModel commodityLocationModel) {
        commodityStorageDao.updateCommodityLocation(commodityLocationModel);
    }

    @Override
    public void deleteCommodityLocation(String serialNo) {
        commodityStorageDao.deleteCommodityLocation(serialNo);
    }

    @Override
    public StockModel queryCommodityUnlocation(StockModel stockModel) {
        return commodityStorageDao.queryCommodityUnlocation(stockModel);
    }

    @Override
    public List<StockModel> queryAllCommodityUnlocation() {
        return commodityStorageDao.queryAllCommodityUnlocation();
    }

    @Override
    public void updateCommodityUnlocation(StockModel stockModel) {
         commodityStorageDao.updateCommodityUnlocation(stockModel);
    }

    @Override
    public void deleteCommodityUnlocation(String serialNo) {
        commodityStorageDao.deleteCommodityUnlocation(serialNo);
    }

    @Override
    public JSONArray queryShelfInfo() {
        return null;
    }

    @Override
    public void addShelfInfo() {

    }

    @Override
    public void deleteShelfInfo() {

    }

    @Override
    public void updateShelfInfo() {

    }

    @Override
    public JSONArray queryShelfCommodityInfo() {
        return null;
    }

}
